package io.kiki.sba.registry.util;

import io.kiki.sba.registry.lifecycle.Suspendable;
import lombok.Getter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 循环执行的任务
 */

public abstract class LoopExecuteTask implements Runnable, Suspendable {
    private static final Logger logger = LoggerFactory.getLogger(LoopExecuteTask.class);

    @Getter
    private volatile boolean closed = false;

    private volatile boolean suspend = false;

    public abstract void _execute_();

    public abstract void _wait_();

    public void close() {
        closed = true;
    }

    @Override
    public void suspend() {
        this.suspend = true;
    }

    @Override
    public void resume() {
        this.suspend = false;
    }

    @Override
    public boolean isSuspended() {
        return suspend;
    }

    public void run() {
        logger.info("任务开始 {}", this.getClass().getSimpleName());
        for (; ; ) {
            if (_loop_execute_()) {
                break;
            }

        }
        logger.info("任务退出 {}, closed={}", this.getClass().getSimpleName(), closed);
    }

    private boolean _loop_execute_() {
        try {
            if (closed) {
                logger.warn("任务关闭!");
                return true;
            }
            if (suspend) {
                logger.warn("[suspend] break");
            } else {
                try {
                    _execute_();
                } catch (Throwable throwable) {
                    logger.error("任务出现异常!", throwable);
                }
            }
            try {
                _wait_();
            } catch (Throwable throwable) {
                logger.error("任务出现异常", throwable);
            }
        } catch (Throwable e) {
            logger.error("loop unexpect error", e);
        }
        return false;
    }
}
